#pragma once

#include "../../include/types.h"
#include "../../include/memlayout.h"
// 中断处理函数类型
typedef void (*interrupt_handler_t)(void);

// 中断类型定义
#define IRQ_S_TIMER    5   // Supervisor timer interrupt
#define IRQ_S_EXTERNAL 9   // Supervisor external interrupt
#define IRQ_S_SOFTWARE 1   // Supervisor software interrupt

// 异常类型定义
#define EXC_INSTRUCTION_MISALIGNED    0
#define EXC_INSTRUCTION_ACCESS_FAULT  1
#define EXC_ILLEGAL_INSTRUCTION       2
#define EXC_BREAKPOINT                3
#define EXC_LOAD_MISALIGNED          4
#define EXC_LOAD_ACCESS_FAULT        5
#define EXC_STORE_MISALIGNED         6
#define EXC_STORE_ACCESS_FAULT       7
#define EXC_ECALL_U_MODE             8
#define EXC_ECALL_S_MODE             9
#define EXC_INSTRUCTION_PAGE_FAULT   12
#define EXC_LOAD_PAGE_FAULT          13
#define EXC_STORE_PAGE_FAULT         15

// 中断向量表大小
#define MAX_IRQ 16

// 中断控制接口
void trap_init(void);
void register_interrupt(int irq, interrupt_handler_t handler);
void unregister_interrupt(int irq);
void enable_interrupt(int irq);
void disable_interrupt(int irq);

// 异常处理接口
void handle_exception(uint64 scause, uint64 sepc, uint64 stval);

// Kernel trap handler (called from S-mode trap vector)
void kerneltrap(void);

// 中断处理函数
void handle_timer(void);
void handle_external(void);
void handle_software(void);

// 异常处理函数
void handle_instruction_page_fault(uint64 sepc, uint64 stval);
void handle_load_page_fault(uint64 sepc, uint64 stval);
void handle_store_page_fault(uint64 sepc, uint64 stval);
void handle_illegal_instruction(uint64 sepc, uint64 stval);
void handle_ecall(uint64 sepc, uint64 stval);

void usertrapret(void);
uint64 usertrap(void);
// 全局变量
extern volatile uint64 ticks;
extern interrupt_handler_t irq_table[MAX_IRQ];

// 测试相关变量
extern volatile int test_interrupt_count;
extern volatile int test_mode;

// SBI接口函数
uint64 get_time(void);
void sbi_set_timer(uint64 time);

void prepare_return(void);
